package conf

import (
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/gomodule/redigo/redis"
	"log"
	"strings"

	//"github.com/chasex/redis-go-cluster"
	_ "github.com/go-sql-driver/mysql"
	"github.com/mna/redisc"
	"h1/logger"
	"h1/models"
	"time"
)

// 定义一个全局的pool
var pool = &redis.Pool{}
var Cluster = &redisc.Cluster{}

func ConnectDataBaseAndRegisterDataBaseModel() {
	_ = orm.RegisterDriver("mysql", orm.DRMySQL)

	dbAlias := DatabaseSetting.DbAlias
	dbName := DatabaseSetting.DbName
	dbPwd := DatabaseSetting.DbPwd
	dbHost := DatabaseSetting.DbHost
	dbUser := DatabaseSetting.DbUser
	dbPort := DatabaseSetting.DbPort
	dbCharset := DatabaseSetting.DbCharset
	tbPrefix := DatabaseSetting.TbPrefix
	/*
		//连接名称
		dbAlias := beego.AppConfig.String("db_alias")
		//数据库名称
		dbName := beego.AppConfig.String("db_name")
		//数据库连接用户名
		dbUser := beego.AppConfig.String("db_user")
		//数据库连接用户名
		dbPwd := beego.AppConfig.String("db_pwd")
		//数据库IP（域名）
		dbHost := beego.AppConfig.String("db_host")
		//数据库端口
		dbPort := beego.AppConfig.String("db_port")
		//数据库编码
		dbCharset := beego.AppConfig.String("db_charset")
		//数据库表前缀
		tbPrefix := beego.AppConfig.String("tb_prefix")
	*/ //注册模型
	registerDataBaseModel(tbPrefix)
	fmt.Println("-------------------------------------")
	err := orm.RegisterDataBase(dbAlias, "mysql", dbUser+":"+dbPwd+"@tcp("+dbHost+":"+dbPort+")/"+dbName+"?charset="+dbCharset+"&loc=Asia%2FShanghai")
	if err != nil {
		fmt.Println("数据库初始化错误", err)
	} else {
		fmt.Println("数据库初始化成功")
		//
		logger.Logger.Info("数据库初始化成功")
	}
	//自动建表
	orm.RunSyncdb(dbAlias, false, true)

	if beego.AppConfig.String("runmode") == "dev" {
		orm.Debug = true
	}
	// 打开调试模式，开发的时候方便查看orm生成什么样子的sql语句
	//orm.Debug = true
	orm.SetMaxIdleConns("default", 20)
	orm.SetMaxOpenConns("default", 100)
	orm.DefaultTimeLoc = time.UTC
}

// 注册数据库模型
func registerDataBaseModel(tbPrefix string) {
	orm.RegisterModelWithPrefix(tbPrefix, new(models.User))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.Project))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.VideoResource))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.ImageResource))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.ProjectScene))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.Scene))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.SceneRelateScene))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.SceneRelateImage))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.SceneRelateVideo))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.Element))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.SceneRelateElement))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.FileDict))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.Theme))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.PreferenceImage))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.Systems))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.VersionDict))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.Loggers))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.SceneVersion))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.Department))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.Role))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.ProjectFile))
	orm.RegisterModelWithPrefix(tbPrefix, new(models.FileResource))

}

func ConnectRedis() {
	redisHost := RedisSetting.RedisHost
	redisPort := RedisSetting.RedisPort
	redisPassword1 := RedisSetting.RedisPassword1
	redisPassword2 := RedisSetting.RedisPassword2
	pool = &redis.Pool{
		MaxIdle:     8,   //最大空闲链接数
		MaxActive:   0,   // 表示和数据库的最大链接数， 0 表示没有限制
		IdleTimeout: 100, // 最大空闲时间
		Dial: func() (redis.Conn, error) { // 初始化链接的代码， 链接哪个ip的redis
			options := redis.DialPassword(redisPassword1 + "#" + redisPassword2)
			return redis.Dial("tcp", redisHost+":"+redisPort, options)
		},
	}
}

func ConnectRedisCluster() {
	redisClusterHost := RedisClusterSetting.RedisClusterHost
	redisClusterPort := RedisClusterSetting.RedisClusterPort
	arr := strings.Split(redisClusterPort, ",")
	for i := range arr {
		arr[i] = redisClusterHost + ":" + arr[i]
	}
	//redisClusterPassword := RedisClusterSetting.RedisCluster
	//Password
	Cluster = &redisc.Cluster{
		StartupNodes: arr,
		//DialOptions:  []redis.DialOption{5 * time.Second},
		CreatePool: createPool,
	}

	//defer cluster.Close()
	if err := Cluster.Refresh(); err != nil {
		log.Fatalf("Refresh failed: %v", err)
	}

	// get a connection from the cluster
	//conn := cluster.Get()
	//s, _ := redis.String(conn.Do("Get", "liu"))
	//fmt.Println(s)
	//defer conn.Close()
}

func GetPool() *redis.Pool {
	return pool
}
func GetConnect() redis.Conn {
	return GetPool().Get()
}

func GetClusterConnect() redis.Conn {
	return Cluster.Get()
}

func createPool(addr string, opts ...redis.DialOption) (*redis.Pool, error) {
	pool = &redis.Pool{
		MaxIdle:     5,
		MaxActive:   10,
		IdleTimeout: time.Minute,
		Dial: func() (redis.Conn, error) {
			return redis.Dial("tcp", addr, opts...)
		},
		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			_, err := c.Do("PING")
			return err
		},
	}
	return pool, nil
}
